看了看成就清單後
發現有幾項沒有寫得很清楚
所以改了一下描述
然後呢
就發現
「挖 我這樣好像用不到表單欸」
經過一番思考
好吧
我就來做一個
好逼真好寫實好重視使用者個資
的
登入畫面
為了達成成就
就這麼辦了
首先我們會需要一些新的狀態資料
// App.jsx
   constructor(){
      super();
      this.state={
         isLogined:false,
         user:"",
      }
      this.login = this.login.bind(this);
      this.logout = this.logout.bind(this);
      this.handleChange = this.handleChange.bind(this);
   }
最基本的要有一個登入與否的識別值
預設狀態是上為登入
另外還要記錄這個使用者是誰
接著
在沒有登入的狀態
理應是不能開始遊戲的
所以我在根組件的位置做一個條件渲染
如果是登入狀態
那就渲染登入的畫面
否則就要請使用者先登入
// App.jsx
   render(){
      if(this.state.isLogined){
         return (
            <div>
               <Router>
                  <div>
                     <h2>Games</h2>
                     <ul>
                        <li><Link to={'/ooxx'}>圈圈叉叉</Link></li>
                        <li><Link to={'/aabb'}>數字猜猜</Link></li>
                        <li><Link to={'/'}>回首頁</Link></li>
                     </ul>
                     <hr/>
                     <Switch>
                        <Route exact path="/"
                               children={
                                 <Home user={this.state.user} onClick={this.logout} />
                                 }  
                        />
                        <Route exact path="/ooxx" component={OX} />
                        <Route exact path='/aabb' component={AB} />
                     </Switch>
                  </div>
               </Router>
            </div>
         );      
      }else{
         return(
            <div>
               <h1>你好,先登入一下如何?</h1>
               <form onSubmit={this.login}>
                  <input type="text" placeholder="請輸入您的大名" onChange={this.handleChange}/>
                  <input type="submit" value="確認" />
               </form>
            </div>
         );
      }
   }
在這裡我有碰到一個問題
呈現登入後畫面的是Home這個組件
可是我是透過 Router 去切換的
那這樣要怎麼把登入的使用者名稱傳遞進去呢?
經過了一番研究Route標籤有一些特定的屬性
其中有一個children的屬性
其中概念就像特殊 props 的那個 children
可以傳遞整個組件用以往 render 函式的寫法
所以這邊我就將登出的函式以及使用者的名稱透過 props 傳遞進去
並且在Home組件呈現這些資料
// Home.jsx
function Home(props){
    return(
        <div>
            <h1>小小遊戲,大大練習!</h1>
            <p>{props.user} 你好啊~</p>
            <p>歡迎來到 ReactJS 的最終激戰</p>
            <p>這裡是首頁,祝天天開心。</p>
            <input type="button" value="登出" onClick={props.onClick} />
        </div>
        );
}
執行畫面:
另外
好的程式習慣可以幫助後續問題處理有更高的效率
所以我去針對每個有接收 props 的組件使用 PropType
若後面加上資料流的時候稍有不慎傳錯資料
就可以更快地找出問題並且修正
首先是Home組件:
Home.jsx
Home.propTypes = {
    user:propTypes.string.isRequired,
    onClick:propTypes.func
}
在Home組件裡我們會使用到使用者的名稱和登出的互動函式
所以這邊傳入兩個props
分別是使用者的名稱user和登出用函式onClick
登入後的畫面一定要完成登入才能看到
所以這邊使用者的名稱被設置成必須
在登出函式被觸發的同時
會清除使用者的名稱為空
// App.jsx
   logout(){
      this.setState({
         isLogined:false,
         user:""
      });
   }
這樣就可以在登入狀態持續持有資料
同時避免因為上個使用者的資料導致可以空白輸入直接登入
另外在輸入是空白狀態的時候點選登入
會出現下面的畫面:
利用 javascript 的 alert 函式
在登入事件被觸發但沒有輸入的狀態產生提醒
login(event) {
      if(this.state.user === ""){
         alert("你忘記你的名字啦!");
         return false;
      }else{
         this.setState({
            isLogined: true
         });
      }
}
接著是遊戲的狀態資料
猜數字遊戲:
// ABList.jsx
ABList.propTypes = {
    data:propTypes.object
}
圈圈叉叉:
// OXList.jsx
OXList.propTypes = {
    data: propTypes.object.isRequired
}
今天複習了表單的使用方法和 proptype
還使用了一個新的 Route 標籤屬性 children
寫出了一個簡單的登入畫面
越來越像個樣子了哈哈哈

- Eva Vue.js 30天隨身包
- Ben那些年,我們一起錯過的Javascript
- Ray激戰ReactJS 30天
Day24 end
by 瑞Ray ( ิ◕㉨◕ ิ)